1 using System;
2 using UnityEngine;
3
4
5 namespace UnityStandardAssets.Cameras
6 {
7 public class TargetFieldOfView : AbstractTargetFollower
8 {
9 // This script is primarily designed to be used with the "LookAtTarget" script to enable a
10 // CCTV style camera looking at a target to also adjust its field of view (zoom) to fit the
11 // target (so that it zooms in as the target becomes further away).
12 // When used with a follow cam, it will automatically use the same target.
13
14 [SerializeField] private float m_FovAdjustTime = 1; // the time taken to adjust the current FOV to the desired target FOV amount.
15 [SerializeField] private float m_ZoomAmountMultiplier = 2; // a multiplier for the FOV amount. The default of 2 makes the field of view twice as wide as required to fit the target.
16 [SerializeField] private bool m_IncludeEffectsInSize = false; // changing this only takes effect on startup, or when new target is assigned.
17
18 private float m_BoundSize;
19 private float m_FovAdjustVelocity;
20 private Camera m_Cam;
21 private Transform m_LastTarget;
22
23 // Use this for initialization
24 protected override void Start()
25 {
26 base.Start();
27 m_BoundSize = MaxBoundsExtent(m_Target, m_IncludeEffectsInSize);
28
29 // get a reference to the actual camera component:
30 m_Cam = GetComponentInChildren<Camera>();
31 }
32
33
34 protected override void FollowTarget(float deltaTime)
35 {
36 // calculate the correct field of view to fit the bounds size at the current distance
37 float dist = (m_Target.position - transform.position).magnitude;
38 float requiredFOV = Mathf.Atan2(m_BoundSize, dist)*Mathf.Rad2Deg*m_ZoomAmountMultiplier;
39
40 m_Cam.fieldOfView = Mathf.SmoothDamp(m_Cam.fieldOfView, requiredFOV, ref m_FovAdjustVelocity, m_FovAdjustTime);
41 }
42
43
44 public override void SetTarget(Transform newTransform)
45 {
46 base.SetTarget(newTransform);
47 m_BoundSize = MaxBoundsExtent(newTransform, m_IncludeEffectsInSize);
48 }
49
50
51 public static float MaxBoundsExtent(Transform obj, bool includeEffects)
52 {
53 // get the maximum bounds extent of object, including all child renderers,
54 // but excluding particles and trails, for FOV zooming effect.
55
56 var renderers = obj.GetComponentsInChildren<Renderer>();
57
58 Bounds bounds = new Bounds();
59 bool initBounds = false;
60 foreach (Renderer r in renderers)
61 {
62 if (!((r is TrailRenderer) || (r is ParticleRenderer) || (r is ParticleSystemRenderer)))
63 {
64 if (!initBounds)
65 {
66 initBounds = true;
67 bounds = r.bounds;
68 }
69 else
70 {
71 bounds.Encapsulate(r.bounds);
72 }
73 }
74 }
75 float max = Mathf.Max(bounds.extents.x, bounds.extents.y, bounds.extents.z);
76 return max;
77 }
78 }
79 }